{-# OPTIONS -fglasgow-exts #-}
module Data.Transform.TransformationHUnit where

import Prelude hiding (catch)
import Data.Transform.Rule
import Data.Transform.TwoLevelPF
import Control.Monad
import Control.Exception (catch)
import IO (isUserError)
import HUnit

-----------------------------------------------------------------------------

main = runTestTT . TestList . map TestCase $ 
    [ testSimpleTag, testSimpleEither, testRightNestedEither, 
      testLeftNestedEither
    ]

-----------------------------------------------------------------------------

testSimpleTag = do
   let format = Tag "One" One
   let (Just evolutedFormat) = enum2int format
   let expectedFormat = Int
   assertEqual "Invalid format" (show expectedFormat) (showType evolutedFormat)
   
   let (Just fv) = forth evolutedFormat expectedFormat ()
   assertEqual "Invalid forward migration" 0 fv
   
   let (Just bv) = back evolutedFormat expectedFormat 0
   assertEqual "Invalid backwards migration" () bv
   

testSimpleEither = do
   let format = Either (Tag "One" One) (Tag "Two" One)
   let (Just evolutedFormat) = enum2int format
   let expectedFormat = Int
   assertEqual "Invalid format" (show expectedFormat) (showType evolutedFormat)
   
   let (Just fv) = forth evolutedFormat expectedFormat (Left ())
   assertEqual "Invalid forward migration" 0 fv
   
   let (Just fv) = forth evolutedFormat expectedFormat (Right())
   assertEqual "Invalid forward migration" 1 fv
   
   let (Just bv) = back evolutedFormat expectedFormat 0
   assertEqual "Invalid backwards migration" (Left ()) bv
   
   let (Just bv) = back evolutedFormat expectedFormat 1
   assertEqual "Invalid backwards migration" (Right ()) bv


testRightNestedEither = do
   let format = Either (Tag "One" One) (Either (Tag "Two" One) (Tag "Three" One))
   let (Just evolutedFormat) = enum2int format
   let expectedFormat = Int
   assertEqual "Invalid format" (show expectedFormat) (showType evolutedFormat)
   
   let (Just fv) = forth evolutedFormat expectedFormat (Left ())
   assertEqual "Invalid forward migration" 0 fv
   
   let (Just fv) = forth evolutedFormat expectedFormat (Right (Left ()))
   assertEqual "Invalid forward migration" 1 fv
   
   let (Just fv) = forth evolutedFormat expectedFormat (Right (Right ()))
   assertEqual "Invalid forward migration" 2 fv
   
   let (Just bv) = back evolutedFormat expectedFormat 0
   assertEqual "Invalid backwards migration" (Left ()) bv
   
   let (Just bv) = back evolutedFormat expectedFormat 1
   assertEqual "Invalid backwards migration" (Right (Left ())) bv
   
   let (Just bv) = back evolutedFormat expectedFormat 2
   assertEqual "Invalid backwards migration" (Right (Right ())) bv


testLeftNestedEither = do
   let format = Either (Either (Tag "One" One) (Tag "Two" One)) (Tag "Three" One)
   let (Just evolutedFormat) = enum2int format

   let expectedFormat = Int
   assertEqual "Invalid format" (show expectedFormat) (showType evolutedFormat)
   
   let (Just fv) = forth evolutedFormat expectedFormat (Left (Left ()))
   assertEqual "Invalid forward migration" 0 fv
   
   let (Just fv) = forth evolutedFormat expectedFormat (Left (Right ()))
   assertEqual "Invalid forward migration" 1 fv
   
   let (Just fv) = forth evolutedFormat expectedFormat (Right ())
   assertEqual "Invalid forward migration" 2 fv
   
   let (Just bv) = back evolutedFormat expectedFormat 0
   assertEqual "Invalid backwards migration" (Left (Left ())) bv
   
   let (Just bv) = back evolutedFormat expectedFormat 1
   assertEqual "Invalid backwards migration" (Left (Right ())) bv
   
   let (Just bv) = back evolutedFormat expectedFormat 2
   assertEqual "Invalid backwards migration" (Right ()) bv
